/*
 * Copyright (c) 2020-2099 the original author or authors. All rights reserve.
 */
package org.tianyun.cloud.security.test;

import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Assert;
import org.tianyun.cloud.security.configuration.SecurityProperties;
import org.tianyun.cloud.security.configuration.SecurityProperties.YamlJwtTokenStrategy;
import org.tianyun.cloud.security.configuration.SecurityProperties.YamlStandardTokenStrategy;
import org.tianyun.cloud.security.configuration.SecurityProperties.YamlTokenStrategy;
import org.tianyun.cloud.security.token.common.AccessToken;
import org.tianyun.cloud.security.token.common.Authentication;
import org.tianyun.cloud.security.token.enhance.TokenSecretEnhance;
import org.tianyun.cloud.security.token.store.InMemoryTokenStore;
import org.tianyun.cloud.security.token.strategy.JwtTokenStrategy;
import org.tianyun.cloud.security.token.strategy.StandardTokenStrategy;
import org.tianyun.cloud.utils.CryptHelper;
import org.tianyun.cloud.utils.JsonUtils;

import java.security.Principal;
import java.util.HashMap;
import java.util.Map;

/**
 * token test
 *
 * @auther ebert_chan
 */
public class TokenGenerateTestCase {

    Logger log = LoggerFactory.getLogger(TokenGenerateTestCase.class);

    @Test
    public void testStandard() {

        YamlStandardTokenStrategy standard = new YamlStandardTokenStrategy();
        standard.setIv(CryptHelper.base64Encrypt(new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}));
        standard.setKey(CryptHelper.base64Encrypt(new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}));

        YamlTokenStrategy tokenStrategy = new YamlTokenStrategy();
        tokenStrategy.setAccessTokenValiditySeconds(7200);
        tokenStrategy.setStandard(standard);

        SecurityProperties securityProperties = new SecurityProperties();
        securityProperties.setTokenStrategy(tokenStrategy);

        String rawName = "test";
        Map<String, Object> map = new HashMap<>();
        map.put("userId", "1");

        Authentication authentication = new Authentication();
        authentication.setName(rawName);
        authentication.setRawValue(map);

        StandardTokenStrategy strategy = new StandardTokenStrategy(securityProperties, new InMemoryTokenStore());
        AccessToken accessToken = strategy.createAccessToken(authentication);
        log.info("standard token value: {}", accessToken.getValue());

        accessToken = strategy.readAccessToken(accessToken.getValue());
        log.info("standard access token: {}", JsonUtils.toJsonString(accessToken));

        Assert.notNull(accessToken, "StandardTokenStrategy test failed.");

    }

    @Test
    public void testJwt() {

        YamlJwtTokenStrategy jwt = new YamlJwtTokenStrategy();
        jwt.setSecret(CryptHelper.base64Encrypt(new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}));
        jwt.setEncryptyData(true);
        jwt.setIv(CryptHelper.base64Encrypt(new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}));
        jwt.setKey(CryptHelper.base64Encrypt(new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}));

        YamlTokenStrategy tokenStrategy = new YamlTokenStrategy();
        tokenStrategy.setAccessTokenValiditySeconds(7200);
        tokenStrategy.setJwt(jwt);

        SecurityProperties securityProperties = new SecurityProperties();
        securityProperties.setTokenStrategy(tokenStrategy);

        String rawName = "test";
        Map<String, Object> map = new HashMap<>();
        map.put("userId", "1");

        Authentication authentication = new Authentication();
        authentication.setName(rawName);
        authentication.setRawValue(map);

        JwtTokenStrategy strategy = new JwtTokenStrategy(securityProperties);
        strategy.setTokenSecretEnhance(new TokenSecretEnhance() {

            @Override
            public String getRandomKey(Principal principal) {
                return "123";
            }
        });
        AccessToken accessToken = strategy.createAccessToken(authentication);
        log.info("jwt token value: {}", accessToken.getValue());

        accessToken = strategy.readAccessToken(accessToken.getValue());
        log.info("jwt access token: {}", JsonUtils.toJsonString(accessToken));

        Assert.notNull(accessToken, "JwtTokenStrategy test failed.");

    }

}
